/**
 * log
 */
class GameLogger {
    static LEVEL_TYPE = {
        No: 0,
        Err: 1000,
        Warn: 2000,
        Info: 3000,
        Debug: 4000,
        Trace: 5000,
    }
    private static _instance: GameLogger;

    public level: number = 4000;

    private constructor() {

    }

    /**
     * 使用单例模式
     */
    private static _getInstance() {
        if (!GameLogger._instance) {
            GameLogger._instance = new GameLogger();
        }
        return GameLogger._instance;
    }

    private static _getDateString() {
        let d = new Date();
        let str = '';
        let timeStr = '';
        str = d.getFullYear() + '';
        timeStr += str + '-';
        str = d.getMonth() + 1 + '';
        timeStr += str + '-';
        str = d.getDate() + '';
        timeStr += str + ' ';
        str = d.getHours() + '';
        timeStr += (str.length == 1 ? '0' + str : str) + ':';
        str = d.getMinutes() + '';
        timeStr += (str.length == 1 ? '0' + str : str) + ':';
        str = d.getSeconds() + '';
        timeStr += (str.length == 1 ? '0' + str : str) + ':';
        str = d.getMilliseconds() + '';
        if (str.length == 1) str = '00' + str;
        if (str.length == 2) str = '0' + str;
        timeStr += str;

        timeStr = '[' + timeStr + ']';
        return timeStr;
    }

    /**
     * 获取调用堆栈
     * @param 
     * @returns 
     */
    public static stack(index) {
        let e = new Error();
        let lines = e.stack.split('\n');
        lines.shift();
        let result = [];
        lines.forEach(function (line) {
            line = line.substring(7);
            let lineBreak = line.split(' ');
            if (lineBreak.length < 2) {
                result.push(lineBreak[0]);
            } else {
                result.push({
                    [lineBreak[0]]: lineBreak[1]
                });
            }
        });

        let list = [];
        if (index < result.length - 1) {
            for (let a in result[index]) {
                list.push(a);
            }
        }

        let splitList = list[0].split('.');
        return (splitList[0] + '.js->' + splitList[1] + ': ');
    }

    /**
     * debug级别log
     */
    public static debug(debug: any) {
        let instance: GameLogger = GameLogger._getInstance();
        if (this.LEVEL_TYPE.Debug <= instance.level) {

            let gameLog = console.log || cc.log;
            let e = new Error();
            // let lines = e.stack.split('\n');
            // let a = lines.shift();
            // 获取调用位置
            let location = e.stack.replace('Error\n', '').split('\n')[1].replace('^\s+|\s+$', '');

            gameLog.call(this, 'BE------------> [Debug] - ' + GameLogger._getDateString() + ' - ' + location + '   =>\n' +
                JSON.stringify(arguments))
        }
    }

    /**
     * info级别log
     */
    public static info(info: any) {
        let instance: GameLogger = GameLogger._getInstance();
        if (this.LEVEL_TYPE.Info <= instance.level) {

            let gameLog = console.log || cc.log;
            let e = new Error();
            // let lines = e.stack.split('\n');
            // let a = lines.shift();
            // 获取调用位置
            let location = e.stack.replace('Error\n', '').split('\n')[1].replace('^\s+|\s+$', '');

            gameLog(this, 'BE------------> [Info] - ' + GameLogger._getDateString() + ' - ' + location + '   =>\n' +
                (info instanceof Object ? JSON.stringify(arguments) : info));
        }
    }

    /**
     * warnning级别log
     */
    public static warn(warn: any) {
        let instance: GameLogger = GameLogger._getInstance();
        if (this.LEVEL_TYPE.Warn <= instance.level) {

            let gameLog = console.log || cc.log;
            let e = new Error();
            // let lines = e.stack.split('\n');
            // let a = lines.shift();
            // 获取调用位置
            let location = e.stack.replace('Error\n', '').split('\n')[1].replace('^\s+|\s+$', '');

            gameLog(this, 'BE------------> [Warn] - ' + GameLogger._getDateString() + ' - ' + location + '   =>\n' +
                (warn instanceof Object ? JSON.stringify(arguments) : warn));
        }
    }

    /**
     * error级别log
     * @param err {Error} 出现错误时的Error对象
     * @param any 用户自定义的输出内容
     */
    public static err(err: any | Error) {
        let instance: GameLogger = GameLogger._getInstance();
        if (this.LEVEL_TYPE.Err <= instance.level) {

            let gameLog = console.log || cc.log;
            if (err instanceof Error) {
                gameLog(this, 'BE------------> [Error] - ' + GameLogger._getDateString() + ' =>\n' +
                    (err instanceof Object ? JSON.stringify(arguments) : err) + '\n' + err.stack + '[End]');
            } else {
                let e = new Error();
                // let lines = e.stack.split('\n');
                // let a = lines.shift();
                // 获取调用位置
                let location = e.stack.replace('Error\n', '').split('\n')[1].replace('^\s+|\s+$', '');

                gameLog(this, 'BE------------> [Error] - ' + GameLogger._getDateString() + ' - ' + location + '   =>\n' +
                    (err instanceof Object ? JSON.stringify(arguments) : err));
            }

        }
    }
}

( < any > window).GameLogger = GameLogger;